package core.gui;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;

public class TextField extends Component{
	
	private final int DX = 4;
	private final int flashingTime = 500; //ms
	
	String text = "";
	boolean isFocus = false;
	boolean isLinePlace = false;
	int linePosition = 0;
	int focusX;
	Font font;
	int flashingTimeCount = 0;
	
	public String getText(){
		return text;
	}
	
	public void setText(String text){
		this.text = text;
	}
	
	public void setFont(Font f){
		this.font = f;
	}
	
	public void mousePressed(MouseEvent e){
		if(!isVisible){
			return;
		}
		int x = e.getX();
		int y = e.getY();
		
		isLinePlace = false;
		if(boundingRect.contains(x, y)){
			isFocus = true;
			focusX = (int) (x - boundingRect.getMinX());
		}else{
			isFocus = false;
		}
	}
	
	public void keyPressed(KeyEvent e){
		if(!isVisible){
			return;
		}
		if(isFocus){
			char c = e.getKeyChar();
			int i = e.getKeyCode();
			if(c == KeyEvent.CHAR_UNDEFINED || i == KeyEvent.VK_BACK_SPACE){
				if(i == KeyEvent.VK_BACK_SPACE && linePosition > 0){
					String first = text.substring(0, linePosition-1);
					String last = text.substring(linePosition, text.length());
					String result = new String(first + last);
					text = result;
					linePosition--;
				}
				if(i == KeyEvent.VK_LEFT){
					linePosition--;
					flashingTimeCount = 0;
					if(linePosition < 0){
						linePosition = 0;
					}
				}
				if(i == KeyEvent.VK_RIGHT){
					linePosition++;
					flashingTimeCount = 0;
					if(linePosition > text.length()){
						linePosition = text.length();
					}
				}
			}else{
				String first = text.substring(0, linePosition);
				String last = text.substring(linePosition, text.length());
				String result = new String(first + c + last);
				text = result;
				linePosition++;
			}
		}
	}
	
	public void render(Graphics2D g){
		if(!isVisible){
			return;
		}
		if(font == null){
			font = g.getFont();
		}
		if(isFocus){
			if(!isLinePlace){
				placeLine(g);
				isLinePlace = true;
			}
			drawLine(g);
		}
		g.setStroke(new BasicStroke(2));
		g.setColor(Color.BLACK);
		g.draw(boundingRect);
		int x = (int) boundingRect.getMinX();
		int y = (int) boundingRect.getCenterY();
		int h = g.getFontMetrics(font).getHeight();
		g.setStroke(new BasicStroke(1));
		g.drawString(text, DX + x, y+h/4);
	}
	
	public void update(int dt){
		if(!isVisible){
			return;
		}
		flashingTimeCount += dt;
		while(flashingTimeCount / flashingTime > 1){
			flashingTimeCount -= 2*flashingTime;
		}
	}
	
	private void placeLine(Graphics2D g){
		FontMetrics fm = g.getFontMetrics(font);
		char [] ca = text.toCharArray();
		boolean isPlace = false;
		for(int i=1; i<=ca.length && !isPlace; i++){
			if(fm.charsWidth(ca, 0, i-1) + fm.charsWidth(ca, i-1, 1)/2 + DX > focusX){
				linePosition = i-1;
				isPlace = true;
			}
		}
		if(!isPlace){
			linePosition = text.length();
		}
	}
	
	private void drawLine(Graphics2D g){
		if(flashingTimeCount / flashingTime == 0){
			FontMetrics fm = g.getFontMetrics(font);
			int px = fm.charsWidth(text.toCharArray(), 0, linePosition);
			int h = fm.getHeight();
			g.drawLine(DX + (int)boundingRect.getMinX() + px, 
					(int)boundingRect.getCenterY() - h/2, 
					DX + (int)boundingRect.getMinX()+ px, 
					(int)boundingRect.getCenterY() + h/2);
		}
	}

}
